package com.zdp.provider.Command;

import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.hystrix.*;

/**
 * 类描述:
 *
 * @author ZhhengDP
 * @since 2021/8/26
 */
public class CommandFacadeWithPrimarySecondary extends HystrixCommand<String> {

    private final static DynamicBooleanProperty userPrimary = DynamicPropertyFactory.
                                                                getInstance().
                                                                getBooleanProperty("primarySecondary.UsePrimary",true);
    private final int id;
    public CommandFacadeWithPrimarySecondary(int id){
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX"))
        .andCommandKey(HystrixCommandKey.Factory.asKey("PrimarySecondaryCommand"))
                // 这边命令的执行采用了信号量隔离的方法
                // 因为具体执行业务逻辑的Command是采用了线程池隔离的方法
        .andCommandPropertiesDefaults(HystrixCommandProperties
                                        .Setter()
                                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)));
        this.id = id;
    }

    @Override
    protected String run() throws Exception {
        if(userPrimary.get()){
            return new PrimaryCommand(id).execute();
        }else{
            return new SecondaryCommand(id).execute();
        }
    }

    /** 当 主/从服务不成功的时候，返回一个静态数据
     * */
    @Override
    protected String getFallback() {
        return "static-fallback" + id;
    }

    // 主服务处理
    private static class PrimaryCommand extends HystrixCommand<String>{
        private  final int id;
        public PrimaryCommand(int id){
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX"))
            .andCommandKey(HystrixCommandKey.Factory.asKey("PrimaryCommand"))
            .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("PrimaryCommand"))
                    // 主服务的执行时间设置为600ms
            .andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(600)));
            this.id = id;
        }

        @Override
        protected String run() throws Exception {
            // 执行主服务具体的处理
            return "responseFromPrimary-" + id;
        }


    }

    // 从服务处理
    private static class SecondaryCommand extends HystrixCommand<String>{
        private  final int id;
        public SecondaryCommand(int id){
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX"))
                    .andCommandKey(HystrixCommandKey.Factory.asKey("SecondaryCommand"))
                    .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("SecondaryCommand"))
                    // 主服务的执行时间设置为100ms
                    .andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(100)));
            this.id = id;
        }

        @Override
        protected String run() throws Exception {
            // 从服务默认返回静态数据
            return "responseFromSecondary-" + id;
        }


    }
}
